<template>
    <el-collapse-item name="3">
        <template #title>
            <h2> Wi-Fi 配置 </h2>
        </template>
        <h3>连接WiFi</h3>
        <el-row :gutter="20">
            <el-col :span="5">
                <b>Wi-Fi名称</b>
            </el-col>
            <el-col :span="15">
                <el-autocomplete id="wifi_join_ssid" clearable placeholder="请输入SSID" v-model="wifi_join.ssid"
                    :fetch-suggestions="querySearch" @select="handleSelect">
                    <template #default="{ item }">
                        <div class="scan_item">
                            {{ item.ssid }}
                            <span>{{ item.rssi }}</span>
                        </div>
                    </template>
                </el-autocomplete>
            </el-col>
            <el-col :span="4">
                <el-button type="primary" :loading="wifi_join.scan" @click="wifi_scan">
                    <span>扫描</span>
                </el-button>
            </el-col>
        </el-row>
        <el-row :gutter="20">
            <el-col :span="5">
                <b>密码</b>
            </el-col>
            <el-col :span="15">
                <el-input v-model="wifi_join.passwd" placeholder="请输入密码" clearable />
            </el-col>
        </el-row>
        <el-alert v-if="show_wifi_join_tips" title="当前仅有终端开启/URL为终端IP, 此时更换 WiFi 会导致连接中断, 无法获取连接状态" type="warning"
            show-icon />
        <el-alert v-if="show_wifi_join_tips" title="连接成功需要手动更换页面 IP 地址" type="warning" show-icon />
        <el-alert v-if="show_wifi_join_tips" title="连接失败后将会重新连接上次成功的 WiFi" type="info" show-icon />
        <el-button type="primary" :disabled="!wifi_join.change" @click="wifi_connect">连接</el-button>

        <br>
        <el-divider></el-divider>
        <el-row :gutter="20">
            <el-col :span="5">
                <b>Wi-Fi模式</b>
                <el-tooltip placement="bottom" effect="light">
                    <template #content>
                        <span v-for="text in tips">
                            {{ text }}<br />
                        </span>
                    </template>
                    <el-icon-QuestionFilled width="20px" />
                </el-tooltip>
            </el-col>
            <el-col :span="15">
                <el-select-v2 v-model="mode" clearable :placeholder='wifi_mode_options[mode].label'
                    :options="wifi_mode_options" />
            </el-col>
            <el-col :span="4">
                <el-button type="primary" :disabled="wifi_mode == mode" @click="save_wifi_mode">保存</el-button>
            </el-col>
        </el-row>

        <br>
        <el-divider></el-divider>
        <el-descriptions title="Wi-Fi 终端(STA)信息" :column="1" border>
            <template #extra>
                <el-switch v-model="sta_set.on" :disabled="!ap_set.on" size="large" active-text="打开"
                    inactive-text="关闭" />
            </template>
            <ElDescriptionsItem label="信号强度">{{ sta_config.signal }} </ElDescriptionsItem>
            <ElDescriptionsItem label="SSID">{{ sta_config.ssid }}</ElDescriptionsItem>
            <ElDescriptionsItem label="MAC">{{ sta_config.mac }}</ElDescriptionsItem>
            <ElDescriptionsItem label="IP">{{ sta_config.ip }}</ElDescriptionsItem>
            <ElDescriptionsItem label="掩码">{{ sta_config.mask }}</ElDescriptionsItem>
            <ElDescriptionsItem label="网关">{{ sta_config.gateway }}</ElDescriptionsItem>
            <ElDescriptionsItem label="DNS">{{ sta_config.dns }}</ElDescriptionsItem>
            <ElDescriptionsItem label="IP 分配模式">
                <el-select-v2 v-model="sta_set.ip_mode" clearable
                    :placeholder='wifi_ip_mode_options[sta_set.ip_mode].label' :options="wifi_ip_mode_options" />
            </ElDescriptionsItem>
            <ElDescriptionsItem v-if="sta_set.ip_mode" label="IP"><el-input v-model="sta_set.ip_config.ip"
                    placeholder="192.168.1.100" clearable />
            </ElDescriptionsItem>
            <ElDescriptionsItem v-if="sta_set.ip_mode" label="掩码"><el-input v-model="sta_set.ip_config.mask"
                    placeholder="255.255.255.0" clearable />
            <ElDescriptionsItem v-if="sta_set.ip_mode" label="网关"><el-input v-model="sta_set.ip_config.gateway"
                    placeholder="192.168.1.1" clearable />
            </ElDescriptionsItem>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="DNS 模式">
                <el-select-v2 v-model="sta_set.dns_mode" clearable
                    :placeholder='wifi_dns_mode_options[sta_config.dns_mode].label' :options="wifi_dns_mode_options" />
            </ElDescriptionsItem>
            <ElDescriptionsItem v-if="sta_set.dns_mode" label="DNS"><el-input v-model="sta_set.dns_config"
                    placeholder="192.168.1.1" clearable />
            </ElDescriptionsItem>
        </el-descriptions>
        <el-button :disabled="!sta_change" type="primary" style="margin-top: 10px;"
            @click="save_sta_info">保存</el-button>

        <br>
        <el-divider></el-divider>
        <el-descriptions title="Wi-Fi 热点(AP)信息" :column="1" border>
            <template #extra>
                <el-switch v-model="ap_set.on" size="large" active-text="打开" inactive-text="关闭" />
            </template>
            <ElDescriptionsItem label="SSID"><el-input v-model="ap_set.ssid" placeholder="请输入WiFi名称" clearable />
            </ElDescriptionsItem>
            <ElDescriptionsItem label="密码"><el-input v-model="ap_set.password" placeholder="请输入WiFi密码" clearable />
            </ElDescriptionsItem>
            <ElDescriptionsItem label="IP">{{ ap_config.ip }}</ElDescriptionsItem>
            <ElDescriptionsItem label="MAC">{{ ap_config.mac }}</ElDescriptionsItem>
            <ElDescriptionsItem label="掩码">{{ ap_config.mask }}</ElDescriptionsItem>
            <ElDescriptionsItem label="网关">{{ ap_config.gateway }}</ElDescriptionsItem>
        </el-descriptions>
        <el-button :disabled="!ap_change" type="primary" style="margin-top: 10px;" @click="save_ap_info">保存</el-button>
    </el-collapse-item>
</template>

<script setup lang="ts">
import Bus from "~/utils/bus";
import { ElMessage } from 'element-plus'
import "element-plus/es/components/message/style/css"
const props = defineProps({
    sta_config: {
        type: Object,
        default: {
            on: false,
            signal: 0,
            ssid: '未连接',
            mac: '未连接',
            ip: '未连接',
            gateway: '未连接',
            mask: '未连接',
            dns: '未连接',
            ip_mode: 0,
            dns_mode: 0,
            ip_config: {
                ip: '未连接',
                gateway: '未连接',
                mask: '未连接',
            },
            dns_config: '未连接'
        }
    },
    ap_config: {
        type: Object,
        default: {
            on: false,
            ssid: '未连接',
            password: "未连接",
            ip: '未连接',
            mac: '未连接',
            gateway: '未连接',
            mask: '未连接',
        }
    },
    wifi_mode: {
        type: Number,
        default: 0
    }
})

interface wifi_scan_result {
    ssid: string,
    rssi: number
}

const wifi_scan_result: wifi_scan_result[] = []
const ap_set = ref({ on: props.ap_config.on, ssid: props.ap_config.ssid, password: props.ap_config.password })
const sta_set = ref({ on: props.sta_config.on, ip_mode: props.sta_config.ip_mode, ip_config: props.sta_config.ip_config, dns_mode: props.sta_config.dns_mode, dns_config: props.sta_config.dns_config })
const ap_change = ref(false)
const sta_change = ref(false)
const mode = ref(props.wifi_mode)
const wifi_join = ref({
    scan: false,
    change: false,
    ssid: '',
    passwd: '',
})
const show_wifi_join_tips = ref(false)

let handle: number = -1;
const get_msg = (result) => {
    if (result.api == 'wifi_scan') {
        wifi_scan_result.splice(0, wifi_scan_result.length)
        wifi_scan_result.push(...result.data)
        wifi_join.value.scan = false;
        document.getElementById('wifi_join_ssid').focus();
        ElMessage.success('WiFi 扫描成功 共有' + wifi_scan_result.length + '个')
        if (handle != -1)
            clearInterval(handle);
    }
}

onBeforeUnmount(() => {
    Bus.off("update:msg", get_msg)
});

onBeforeMount(() => {
    Bus.on("update:msg", get_msg);
});

watchEffect(() => {
    ap_change.value = false
    sta_change.value = false
    if (
        props.ap_config.on != ap_set.value.on ||
        props.ap_config.ssid != ap_set.value.ssid ||
        props.ap_config.password != ap_set.value.password
    )
        ap_change.value = true
    if (
        props.sta_config.on != sta_set.value.on ||
        props.sta_config.ip_mode != sta_set.value.ip_mode ||
        props.sta_config.dns_mode != sta_set.value.dns_mode ||
        (props.sta_config.dns_config != sta_set.value.dns_config && isValidIp(sta_set.value.dns_config)) ||
        (props.sta_config.ip_config.ip != sta_set.value.ip_config.ip && isValidIp(sta_set.value.ip_config.ip)) ||
        (props.sta_config.ip_config.gateway != sta_set.value.ip_config.gateway && isValidIp(sta_set.value.ip_config.gateway)) ||
        (props.sta_config.ip_config.mask != sta_set.value.ip_config.mask && isValidIp(sta_set.value.ip_config.mask))
    )
        sta_change.value = true
    if ((sta_set.value.on && !ap_set.value.on) || props.sta_config.ip == window.location.hostname)
        show_wifi_join_tips.value = true
    if (wifi_join.value.ssid.length != 0 && wifi_join.value.passwd.length >= 6)
        wifi_join.value.change = true;
})

const wifi_scan = () => {
    if (!wifi_join.value.scan) {
        wifi_join.value.scan = true
        Bus.emit('push.msg', { api: "wifi_scan" })
        let count = 0;
        handle = setInterval(() => {
            if (++count >= 60) {
                clearInterval(handle);
                handle = -1;
                ElMessage.error('WiFi 扫描失败')
                wifi_join.value.scan = false
            }
        }, 500)
    }
}

const querySearch = (queryString: string, cb) => {
    cb(wifi_scan_result)
}

const handleSelect = (item: wifi_scan_result) => {
    console.log(item)
    wifi_join.value.ssid = item.ssid
}

const wifi_connect = () => {
    wifi_join.value.change = false
    Bus.emit('push.msg', { api: "wifi_connect", data: { ssid: wifi_join.value.ssid, password: wifi_join.value.passwd } })
}

const save_wifi_mode = () => {
    Bus.emit('push.msg', { api: "wifi_mode", data: mode })
}

const save_sta_info = () => {
    Bus.emit('push.msg', { api: "wifi_config_sta", data: sta_set.value })
}

const save_ap_info = () => {
    Bus.emit('push.msg', { api: "wifi_config_ap", data: ap_set.value })
}

const wifi_ip_mode_options = [
    {
        value: 0,
        label: '自动(DHCP)',
    },
    {
        value: 1,
        label: '静态IP',
    },
]
const wifi_dns_mode_options = [
    {
        value: 0,
        label: '自动(使用网关)',
    },
    {
        value: 1,
        label: '静态DNS',
    },
]
const wifi_mode_options = [
    {
        value: 0,
        label: '智能热点+常开终端(AP+STA)',
    },
    {
        value: 1,
        label: '仅开启热点(AP)',
    },
    {
        value: 2,
        label: '(不推荐) 常开热点+常开终端(AP+STA)',
    },
]

const isValidIp = (arg) => {
    var regEx = /,/g
    var ipList = arg.toString().replace(regEx, ',').split(',')
    var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
    var pattern = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\/(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
    for (var i in ipList) {
        if (!reg.test(ipList[i]) && !pattern.test(ipList[i])) {
            return false
        }
    }
    return true
}
const tips = [
    '热点+终端模式并存会影响稳定性。且保持热点开启会增加功耗。',
    '智能模式： 成功连接Wi-Fi，30秒后自动关闭热点；断开连接，5秒后自动打开热点',
    '热点+终端共存模式： 方便使用，但是影响稳定性',
    '单热点模式缺点： 无网络'
]
</script>

<style scoped>
.scan_item {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
</style>